import org.codehaus.groovy.grails.plugins.springsecurity.Secured
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap

@Secured(['ROLE_ADMIN', 'ROLE_POWER_USER'])
class TypeManagerController {

    /** VIEWS **/
    def create = {
        renderView(params, 'create')
    }

    def edit = {
        renderView(params, 'edit')
    }

    def index = {
        renderView(params, 'list')
    }

    def list = {
        renderView(params, 'list')
    }

    def select = {}

    def show = {
        renderView(params, 'show')
    }

    /** ACTIONS **/
    def delete = {
        def clazz = getClazz(params.id)
        if (!clazz) {
            return
        }

        def type = clazz.get(params.index)

        if (type) {
            type.delete(flush:true)
        }
        renderView(params, 'list')
    }

    def save = {
        println "saving"
        def clazz = getClazz(params.id)
        if (!clazz) {
            return
        }

        def type = clazz.newInstance()
        type.properties = params

        if (type.save()) {
            renderView(params, 'list')
        } else {
            render view: 'create', model: [type: type, title: params.id]
        }
    }

    def update = {
        println "updating"
        println params
        def clazz = getClazz(params.id)
        if (!clazz) {
            return
        }

        def type = clazz.get(params.index)
        type.properties = params
        
        if (type.save()) {
            renderView(params, 'list')
        } else {
            render view: 'create', model: [type: type, title: params.id]
        }
    }

    /** UTILITIES **/
    private Class getClazz(String className) {
        try {
            return Thread.currentThread().contextClassLoader.loadClass(params.id)
        } catch (ClassNotFoundException ex) {
            render view: 'select'
            flash.message("The type '${params.id}' was not found. If this error persists please tell the admin.")
            return null
        } catch (NullPointerException ex) {
            render view: 'list'
            flash.message("There was an error saving the '${params.id}'. If this error persists please tell the admin.")
            return null
        }
    }

    private void renderView(GrailsParameterMap params, String view) {
        println "render view " + params
        if (!params.id) {
            render view: 'select'
            return
        }

        def clazz
        try {
            clazz = Thread.currentThread().contextClassLoader.loadClass(params.id)
        } catch (ClassNotFoundException ex) {
            render view: 'select'
            return
        }

        def data
        switch (view) {
            case 'edit':
                data = clazz.get(params.index)
                break
            case 'list':
                if (!params.max) {
                    params.max = 10
                }
                data = clazz.list(params)
                break
            case 'show':
                data = clazz.get(params.index)
                break
            default:
                data = clazz.newInstance()
        }
        render view: view, model: [type: data, typeTotal: clazz.count(), title: params.id]
    }
}
